/***********************************************************************************
 * 文件名： mcu_wdt.c
 * 作者： 黄均铭
 * 版本： 1
 * 说明：
 * 		看门狗驱动。
 * 修改记录：
 * 	2024年1月19日: 初版。 黄均铭。
 ***********************************************************************************/
#include "mcu_wdt.h"

#if _WDT_ENABLE != 0
// WDT解锁值
#define _WDT_UNLOCK_VALUE 0x55AA6699

// WDT清除值
#define _WDT_CLEAR_VALUE 0x55AA55AA

// 看门狗启动标记
bool mWdtEnable;

// 按照配置文件对WDT进行初始化，会启动WDT且不可以再关闭
// 注意，即便是复位，WDT也不可以被关闭或修改寄存器，必须彻底断电一段时间。
// 意味着不断电，直接修改代码配置，即便重新烧录，新的配置也不会生效，需要先断电清除之前的配置。
void Wdt_Init(void)
{
    // 关闭看门狗
    mWdtEnable = false;

    // 解锁看门狗寄存器
    WDT->LOCK = _WDT_UNLOCK_VALUE;

    // 初始化并启动看门狗
    WDT->LOAD = _WDT_TIME_CYCLE;
    WDT->ICLR = _WDT_CLEAR_VALUE;
    WDT->CON = (0x5A << 8) | (_WDT_TIME_PRS << 2) | 0x01;

    // 锁定看门狗寄存器
    WDT->LOCK = 0;

    // 看门狗中断
    NVIC_ClearPendingIRQ(WDT_IRQn); // 清除NVIC中断标志位
    NVIC_SetPriority(WDT_IRQn, 0);  // 优先级 3 （0~3）
    NVIC_EnableIRQ(WDT_IRQn);       // NVIC允许中断

    // 开启看门狗
    mWdtEnable = true;
}

// 修改看门狗时间，单位：ms
void Wdt_SetTime(u16 time)
{
    // 解锁看门狗寄存器
    WDT->LOCK = _WDT_UNLOCK_VALUE;
    // 初始化并启动看门狗
    WDT->LOAD = time * 40;
    WDT->ICLR = _WDT_CLEAR_VALUE;
    // 锁定看门狗寄存器
    WDT->LOCK = 0;
}

// 清除看门狗中断标记
void Wdt_Clear(void)
{
    // 解锁看门狗寄存器
    WDT->LOCK = _WDT_UNLOCK_VALUE;
    // 清除中断标记位
    WDT->ICLR = _WDT_CLEAR_VALUE;
    // 锁定看门狗寄存器
    WDT->LOCK = 0;
}

// 看门狗中断
void WDT_IRQHandler(void)
{
    if (mWdtEnable)
    {
        // 使能情况下，复位
        Pow_Reset();
    }

    Wdt_Clear();
}

#endif
